home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / program / fpk65_66.zip / SOURCE / RTL / DOS / LINE.PPI < prev    next >
Text File  |  1997-01-27  |  13KB  |  511 lines

  1. procedure DrawPattern(x1,x2,y:integer);
  2. begin
  3.   asm
  4.     movswl x1,%ebx
  5.     movswl x2,%ecx
  6.     movswl y,%edx
  7.     subl   %ebx,%ecx
  8.     incl   %ecx
  9.     movl   _X_ARRAY(,%ebx,4),%eax
  10.     movl   _Y_ARRAY(,%edx,4),%edi       // { Offset in %edi }
  11.     addl   %eax,%edi
  12.     andl   _WINLOMASK,%edi
  13.     andl   $0x7,%edx                    // { y and $7                }
  14.     shll   $0x5,%edx                    // { y * 8 * sizeof(longint) }
  15.     leal   _PATTERNBUFFER,%esi          // 
  16.     addl   %edx,%esi                    // { Offset in Patternbuffer }
  17.     movl   $0x7,%edx
  18.     addl   _WBUFFER,%edi
  19.     pushw  %es
  20.     movw   _SEG_WRITE,%ax
  21.     movw   %ax,%es
  22.     testw  $1,_AKTWRITEMODE
  23.     jnz    pl_xord
  24.  pl_movd:
  25.     testw  $1,_BYTESPERPIXEL
  26.     jz     pl_movdw
  27.  
  28.  .align 4,0x90
  29.  pl_movdb:
  30.     andl   %edx,%ebx
  31.     movb   (%esi,%ebx,4),%al
  32.     movb   %al,%es:(%edi)
  33.     incl   %edi
  34.     incl   %ebx
  35.     decl   %ecx
  36.     jnz    pl_movdb
  37.     jz     pl_d_exit    
  38.  
  39.  .align 4,0x90
  40.  pl_movdw:
  41.     andl   %edx,%ebx
  42.     movw   (%esi,%ebx,4),%ax
  43.     movw   %ax,%es:(%edi)
  44.     addl   $2,%edi
  45.     incl   %ebx
  46.     decl   %ecx
  47.     jnz    pl_movdw
  48.     jz     pl_d_exit    
  49.  pl_xord:
  50.     testw  $1,_BYTESPERPIXEL
  51.     jz     pl_xordw
  52.  .align 4,0x90
  53.  pl_xordb:
  54.     andl   %edx,%ebx
  55.     movb   (%esi,%ebx,4),%al
  56.     xorb   %al,%es:(%edi)
  57.     incl   %edi
  58.     incl   %ebx
  59.     decl   %ecx
  60.     jnz    pl_xordb
  61.     jz     pl_d_exit 
  62.  .align 4,0x90
  63.  pl_xordw:
  64.     andl   %edx,%ebx
  65.     movw   (%esi,%ebx,4),%ax
  66.     xorw   %ax,%es:(%edi)
  67.     addl   $2,%edi
  68.     incl   %ebx
  69.     decl   %ecx
  70.     jnz    pl_xordw
  71.  pl_d_exit:
  72.     popw   %es
  73.  pl_exit:
  74.  end;
  75. end;
  76.  
  77. procedure PatternLine(x1,x2,y:integer);
  78. var bank1,bank2    : longint;
  79.     ofs1,ofs2      : longint;
  80.     diff           : integer;
  81.     viewport       : ViewPortType;
  82. begin
  83.   x1:= x1 + aktviewport.x1 ;
  84.   y:=  y +  aktviewport.y1 ;
  85.   x2:= x2 + aktviewport.x1 ;
  86.   
  87.   if aktviewport.clip then viewport:=aktviewport else viewport:=aktscreen;
  88.   if (y < viewport.y1) or (y > viewport.y2) then exit;
  89.   if x1 > x2 then begin diff:=x2; x2:=x1; x1:=diff; end;
  90.   if (x1> viewport.x2) or (x2< viewport.x1) then exit;
  91.   if x1 < viewport.x1 then x1:=viewport.x1;
  92.   if x2 > viewport.x2 then x2:=viewport.x2;
  93.   ofs1:= Y_ARRAY[y];
  94.   ofs2:= ofs1 + X_ARRAY[x2];
  95.   ofs1:= ofs1 + X_ARRAY[x1];
  96.   bank1:=ofs1 shr winshift;
  97.   bank2:=ofs2 shr winshift;
  98.   if bank1 <> AW_BANK then
  99.   begin
  100.     Switchbank(bank1);
  101.     AW_BANK:=bank1;
  102.   end;
  103.   if bank1 <> bank2 then begin
  104.      diff:=(((bank2 shl winshift)-ofs1) div BytesPerPixel)+x1;  
  105.      DrawPattern(x1,diff-1,y);
  106.      Switchbank(bank2); AW_BANK:=bank2;
  107.      DrawPattern(diff,x2,y);
  108.   end else DrawPattern(x1,x2,y);
  109. end;
  110.  
  111.  
  112. procedure HorizontalLine(x1,x2,y:integer);
  113. { without bankswitching }
  114. begin
  115.   asm
  116.     movw   %es,%dx
  117.     movzwl y,%ebx
  118.     movzwl x1,%eax
  119.     movzwl x2,%ecx
  120.     incl   %ecx
  121.     movl   _X_ARRAY(,%eax,4),%eax
  122.     movl   _X_ARRAY(,%ecx,4),%ecx
  123.     movl   _Y_ARRAY(,%ebx,4),%edi       // { Offset in %edi }
  124.     subl   %eax,%ecx                    // { Counter }
  125.     addl   %eax,%edi
  126.     andl   _WINLOMASK,%edi
  127.     movl   _AKTCOLOR,%eax
  128.     movzwl _AKTWRITEMODE,%esi
  129.     addl   _WBUFFER,%edi    
  130.     movw   _SEG_WRITE,%bx
  131.     movw   %bx,%es 
  132.     testl  %esi,%esi                    // { Writemode ?       }
  133.     jnz    hl_xor
  134.     shrl   %ecx
  135.     jnc    _movw
  136.     stosb
  137.  _movw:
  138.     shrl   %ecx
  139.     jnc    _movd
  140.     stosw
  141.  _movd:
  142.     rep
  143.     stosl
  144.     jmp    hl_exit
  145.  
  146.  hl_xor:   // -------------------------------------------------
  147.  
  148.     movl   $4,%esi
  149.     shrl   %ecx
  150.     jnc    hl_xorw
  151.     xorb   %al,%es:(%edi)
  152.     incl   %edi 
  153.  hl_xorw:
  154.     shrl   %ecx
  155.     jnc    hl_xord
  156.     xorw   %ax,%es:(%edi)
  157.     addl   $2,%edi
  158.  hl_xord:   
  159.     jecxz  hl_exit
  160.  .align 4,0x90
  161.  hl_xorloop:
  162.     xorl   %eax,%es:(%edi)
  163.     addl   %esi,%edi
  164.     decl   %ecx
  165.     jnz    hl_xorloop
  166.  hl_exit:
  167.     movw   %dx,%es
  168.  end;
  169. end;
  170.  
  171. procedure Line(x1,y1,x2,y2: integer);
  172. var dx,dy,d        : longint;
  173.     i,j            : integer; 
  174.     ofs,ofs2       : longint;
  175.     i1,i2,ix       : longint; 
  176.     x,y            : Integer; 
  177.     flag,dontcheck : Boolean;
  178.     viewport       : ViewPortType;
  179. begin
  180.   
  181.   x1:= x1 + aktviewport.x1 ;
  182.   y1:= y1 + aktviewport.y1 ;
  183.   x2:= x2 + aktviewport.x1 ;
  184.   y2:= y2 + aktviewport.y1 ;
  185.   if aktviewport.clip then viewport:=aktviewport else viewport:=aktscreen;
  186.   
  187.   { ************ Horizontalline ************** }
  188.  
  189.   if y1=y2 then begin
  190.     if x1>x2 then begin d:=x1; x1:=x2; x2:=d; end; 
  191.     if aktlineinfo.thickness=3 then y1:=y1-1;
  192.     i:=0;
  193.     if x1 < viewport.x1 then x1:=viewport.x1;
  194.     if x2 > viewport.x2 then x2:=viewport.x2;
  195.     if (y1 > viewport.y2) or (x1 > x2 ) then exit;
  196.     repeat  
  197.       if (y1 >= viewport.y1) and (y1 <=viewport.y2) 
  198.       then begin
  199.         ofs:= Y_ARRAY[y1];
  200.         ofs2:=ofs+X_ARRAY[x2];
  201.         ofs:= ofs+X_ARRAY[x1];
  202.         i1:=ofs shr winshift; i2:=ofs2 shr winshift;
  203.         if i1 <> aw_bank then 
  204.           begin 
  205.             switchbank(i1); 
  206.             aw_bank:=i1; 
  207.           end;
  208.         if i1=i2 then Horizontalline(x1,x2,y1)
  209.           else                             
  210.             begin 
  211.             dx:=((i2 shl winshift)-ofs) div BytesPerPixel;
  212.             horizontalline(x1,x1+dx-1,y1);
  213.             Switchbank(i2); AW_BANK:=i2;
  214.             horizontalline(dx+x1,x2,y1); 
  215.           end;
  216.       end;
  217.       i:=i+1; y1:=y1+1;
  218.     until i=aktlineinfo.thickness;  
  219.     exit;
  220.   end;  
  221.   
  222.   { *********** End Horizontalline *********** }
  223.  
  224.   if y1 > y2 then begin
  225.     x:=x1; x1:=x2; x2:=x;
  226.     y:=y1; y1:=y2; y2:=y;
  227.   end;
  228.  
  229.   { ************** Verticalline ************** }
  230.  
  231.   if x1=x2 then
  232.   begin
  233.     if y1 < viewport.y1 then y1:=viewport.y1;
  234.     if y2 > viewport.y2 then y2:=viewport.y2;
  235.     if ( y1 > y2) or (x1 < viewport.x1) or (x1 > viewport.x2) then exit;
  236.     ofs:= Y_Array[y2]+X_Array[x1];
  237.     ofs2:=Y_Array[y1]+X_Array[x1];
  238.     while ofs >= ofs2 do begin
  239.        pixel(ofs);
  240.        if aktlineinfo.thickness=3 then begin
  241.          if x1>viewport.x1 then pixel(ofs-1);
  242.          if x1<viewport.x2 then pixel(ofs+1);
  243.        end;
  244.        ofs:=ofs-BytesPerLine;
  245.     end;
  246.     exit;
  247.   end;
  248.  
  249.   { ************ End Verticalline ************ }
  250.  
  251.   dy:=y2-y1;
  252.   dx:=abs(x2-x1);
  253.   if x1>x2 then ix:=-1 else ix:= 1;
  254.   if dx<dy then begin d:=dx; dx:=dy; dy:=d; Flag:=true end else Flag:=false;
  255.   i1:=dy shl 1;
  256.    d:=i1 - dx;
  257.   i2:=(dx shl 1)-i1;
  258.  
  259. dontcheck:=(y1>=viewport.y1) and (y2<=viewport.y2) and 
  260.            (x1>=viewport.x1) and (x1<=viewport.x2) and
  261.            (x2>=viewport.x1) and (x2<=viewport.x2);
  262.  
  263. if aktlineinfo.thickness=3 then 
  264.  
  265.     { *************************************** }
  266.     { **** Thickness=3 with rangechecking *** }
  267.     { *************************************** } 
  268.     
  269. begin
  270.   repeat
  271.     for i:=y1-1 to y1+1 do
  272.       for j:=x1-1 to x1+1 do 
  273.       if (i>=viewport.y1) and (j>=viewport.x1) and 
  274.          (j<=viewport.x2) and (i<=viewport.y2) then pixel(X_ARRAY[j]+Y_ARRAY[i]);
  275.     if d < 0
  276.     then begin 
  277.       if Flag then y1:=y1+1 else x1:=x1+ix;
  278.       d:=d+i1;
  279.     end  
  280.     else begin
  281.       d:=d-i2; x1:=x1+ix; y1:=y1+1;
  282.     end; 
  283.   dx:=dx-1;
  284.   until ( dx=0 ) or ( y1 > viewport.y2 )
  285. end else 
  286.   if dontcheck then
  287.  
  288.     { *************************************** }
  289.     { ** Thickness=1 without rangechecking ** }
  290.     { *************************************** } 
  291.     
  292.     begin 
  293.     asm
  294.      pushw  %gs
  295.      movw   _SEG_WRITE,%ax
  296.      movw   %ax,%gs                   // { ScreenSelector }
  297.   
  298.   // selfmodify to speedup Code   
  299.      xorl   %ebx,%ebx
  300.      movl   ix,%eax
  301.      testl  %eax,%eax
  302.      jns    line1_inc
  303.      movl   $0x08,%ebx
  304.    line1_inc:
  305.      addl   $0x43,%ebx                // Opcode incl %ebx
  306.      movb   %bl,inc_dec1
  307.      movb   %bl,inc_dec2
  308.      movl   i1,%eax
  309.      movl   %eax,i1long1
  310.      movl   %eax,i1long2
  311.      movl   i2,%eax
  312.      movl   %eax,i2long
  313.      movl   _WBUFFER,%eax
  314.      movl   %eax,wbuffer
  315.      movl   _WINSHIFT,%eax
  316.      movb   %al,winshift
  317.      movl   _WINLOMASK,%eax
  318.      movl   %eax,winlomask
  319.      movb   $0x90,operandprefix       // Opcade nop  
  320.      testw  $1,_AKTWRITEMODE
  321.      jnz    line1XOR
  322.      movb   $0x88,linemode            // Opcode movb
  323.      jmp    linedepth
  324.     line1XOR:
  325.       movb   $0x30,linemode           // Opcode xorb
  326.     linedepth:  
  327.       testw  $1,_BYTESPERPIXEL
  328.       jnz    is_byte
  329.       movb   $0x66,operandprefix      // Prefix for operandsize
  330.       incb   linemode                 // incr. for wordacces
  331.     is_byte:      
  332.       movl   dx,%ecx
  333.       movl   _AKTCOLOR,%eax
  334.       movzwl y1,%esi
  335.       movzwl x1,%ebx
  336.       movswl d,%edx
  337.    //----------------//
  338.    //  Linemainloop  //
  339.    //----------------//   
  340. .align 4,0x90
  341. line1_loop:  
  342.       pushl  %ecx
  343.       pushl  %eax
  344.       movl   _Y_ARRAY(,%esi,4),%edi
  345.       addl   _X_ARRAY(,%ebx,4),%edi
  346.       movl   %edi,%eax
  347.       .byte 0x81,0xe7                 // andl ..,%edi
  348.     winlomask:                        //
  349.       .long 0x88888888                // _WINLOMASK
  350.       .byte 0xc1,0xe8                 // shrl ..,%eax
  351.     winshift:                         //
  352.       .byte 0x88                      // _WINSHIFT
  353.       
  354.       pushl  %edi
  355.       cmpl   _AW_BANK,%eax
  356.       je     line1_dontswitch
  357.       
  358.       pushl  %ebx
  359.       pushl  %edx
  360.       pushl  %esi   
  361.       movl   %eax,_AW_BANK             // newbank
  362.       pushl  %eax
  363.       movl   _BANKSWITCHPTR,%eax
  364.       call   %eax
  365.       popl   %esi
  366.       popl   %edx
  367.       popl   %ebx
  368. .align 4,0x90
  369. line1_dontswitch:
  370.       popl   %edi
  371.       popl   %eax
  372.       popl   %ecx
  373.      .byte   0x81,0xc7                 // addl ..,%edi
  374.     wbuffer:                           //
  375.      .long   0x88888888                // _WBUFFER
  376.     operandprefix:
  377.      .byte   0x90                      // Operandprefix (nop for Byte,$66 for Word)
  378.      .byte   0x65                      // Segmentprefix %gs:
  379.     linemode:
  380.      .byte   0x88,0x07                 // modified OpCode<movb,xorb...>,%edi
  381.       decl   %ecx
  382.       jz     line1_end      
  383.       testl  %edx,%edx                 // { if d < 0 then }
  384.       jns    is_positive
  385.       testb  $1,flag                   // { if flag then }
  386.       jz     no_flag
  387.       incl   %esi                      // { y1:=y1+1  }   
  388.      .byte   0x81,0xc2
  389.     i1long1:   
  390.      .long   0x88888888                // { d:=d+i1   }
  391.       jmp    line1_loop
  392. .align 4,0x90
  393. no_flag:
  394.     inc_dec1: 
  395.      .byte   0x88                      // { x1:=x1+ix }   
  396.      .byte   0x81,0xc2
  397.     i1long2:   
  398.      .long   0x88888888                // { d:=d+i1   }
  399.       jmp    line1_loop
  400. .align 4,0x90
  401. is_positive:
  402.     inc_dec2:  
  403.      .byte   0x88                      // { x1:=x1+ix }
  404.       incl   %esi                      // { y1:=y1+1  }      
  405.      .byte   0x81,0xea 
  406.     i2long:  
  407.      .long   0x88888888                // { d:=d-i2   }
  408.       jmp    line1_loop
  409. line1_end:
  410.       popw   %gs
  411.     end;
  412.   end else
  413.     
  414.     { *************************************** }
  415.     { **** Thickness=1 with rangechecking *** }
  416.     { *************************************** } 
  417.     
  418.     begin
  419.     repeat
  420.       if y1 > viewport.y2 then exit;
  421.       if (y1>=viewport.y1) and (x1>=viewport.x1) and 
  422.          (x1<=viewport.x2) then pixel(Y_ARRAY[y1]+X_ARRAY[x1]);    
  423.       if d < 0
  424.       then begin 
  425.         if Flag then y1:=y1+1 else x1:=x1+ix;
  426.         d:=d+i1;
  427.       end  
  428.       else begin
  429.         d:=d-i2; x1:=x1+ix; y1:=y1+1;
  430.       end; 
  431.     dx:=dx-1;
  432.     until  dx=0 ;
  433.   end;
  434. end;
  435.  
  436. procedure MoveTo(x,y : integer);
  437. begin
  438.   _graphresult:=grOk;
  439.   if not isgraphmode then
  440.      begin
  441.        _graphresult:=grnoinitgraph;
  442.        exit;
  443.      end;
  444.   curx:=x;
  445.   cury:=y;
  446. end;
  447.  
  448. procedure MoveRel(dx,dy : integer);
  449. begin
  450.   _graphresult:=grOk;
  451.   if not isgraphmode then
  452.      begin
  453.        _graphresult:=grnoinitgraph;
  454.        exit;
  455.      end;
  456.   curx:=curx+dx;
  457.   cury:=cury+dy;
  458. end;
  459.  
  460. procedure LineTo(x,y : integer);
  461. begin
  462.   _graphresult:=grOk;
  463.   if not isgraphmode then
  464.      begin
  465.        _graphresult:=grnoinitgraph;
  466.        exit;
  467.      end;
  468.   Line(curx,cury,x,y);
  469.   MoveTo(x,y);
  470. end;
  471.  
  472. procedure LineRel(dx,dy : integer);
  473. begin
  474.   _graphresult:=grOk;
  475.   if not isgraphmode then
  476.      begin
  477.        _graphresult:=grnoinitgraph;
  478.      exit;
  479.    end;
  480.   Line(curx,cury,curx+dx,cury+dy);
  481.   curx:=curx+dx; 
  482.   cury:=cury+dy;
  483. end;
  484.  
  485. procedure SetLineStyle(LineStyle : word;pattern : word;thickness : word);
  486. const
  487.   linepatterns : array[0..3] of word =
  488.   ($ffff,$aaaa,$fafa,$ffff);
  489.  
  490. begin
  491.   _graphresult:=grOk;
  492.   if not isgraphmode then
  493.     begin
  494.       _graphresult:=grnoinitgraph;
  495.       exit;
  496.     end;
  497.   if (linestyle<0) or (linestyle>4) or
  498.      ((thickness<>1) and (thickness<>3)) then
  499.      begin
  500.        _graphresult:=grerror;
  501.        exit;
  502.      end;
  503.      aktlineinfo.linestyle:=linestyle;
  504.      if aktlineinfo.linestyle=UserBitLn then
  505.         aktlineinfo.pattern:=pattern
  506.         else
  507.         aktlineinfo.pattern:=linepatterns[aktlineinfo.linestyle];
  508.         aktlineinfo.thickness:=thickness;
  509. end;
  510.  
  511.